package com.symaster.backups.manager;

import org.springframework.stereotype.Component;

import java.util.Hashtable;

/**
 * @author yinmiao
 * @version 2024/2/23
 */
@Component
public class TaskManager {

    private final Hashtable<String, Runnable> taskMap = new Hashtable<>();
    private final Hashtable<String, TaskConfig> configMap = new Hashtable<>();

    public void taskExec(String taskName, Runnable runnable) {
        TaskConfig taskConfig = configMap.computeIfAbsent(taskName, s -> taskConfigInit());

        synchronized (taskConfig.treeLock) {
            if (taskConfig.run) {
                try {
                    taskConfig.running = true;
                    runnable.run();
                } finally {
                    taskConfig.running = false;
                    taskConfig.treeLock.notifyAll();
                }
            }
        }
    }

    public void stopTask(String taskName) {
        TaskConfig taskConfig = configMap.computeIfAbsent(taskName, s -> taskConfigInit());

        synchronized (taskConfig.treeLock) {
            taskConfig.run = false;
            if (taskConfig.running) {
                try {
                    taskConfig.treeLock.wait();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

    public void startTask(String taskName) {
        TaskConfig taskConfig = configMap.computeIfAbsent(taskName, s -> taskConfigInit());

        synchronized (taskConfig.treeLock) {
            if (!taskConfig.run) {
                taskConfig.run = true;
            }
        }
    }

    private TaskConfig taskConfigInit() {
        return new TaskConfig(new Object(), true, false);
    }

    private static class TaskConfig {
        final Object treeLock;
        boolean run;
        boolean running;

        public TaskConfig(Object treeLock, boolean run, boolean running) {
            this.treeLock = treeLock;
            this.run = run;
            this.running = running;
        }
    }
}
